package com.jichangxiu.server.platform.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.jichangxiu.common.constant.Constant;
import com.jichangxiu.common.entity.bo.Record;
import com.jichangxiu.common.entity.bo.SecurityPower;
import com.jichangxiu.common.entity.bo.SecurityRole;
import com.jichangxiu.common.entity.bo.SecurityUser;
import com.jichangxiu.framework.security.service.AuthUserDetailsService;
import com.jichangxiu.server.platform.entity.dto.PlatformTenantQueryDto;
import com.jichangxiu.server.platform.entity.po.PlatformMenuPower;
import com.jichangxiu.server.platform.entity.po.PlatformRole;
import com.jichangxiu.server.platform.entity.po.PlatformUser;
import com.jichangxiu.server.platform.service.PlatformTenantService;
import com.jichangxiu.server.platform.service.PlatformUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * JcxUserDetailsServiceImpl:
 *
 * @author Jcx
 * @create 2023-02-26 20:57
 */
@Service
public class AuthUserDetailsServiceImpl implements AuthUserDetailsService {

    private PlatformUserService platformUserService;

    private PlatformTenantService platformTenantService;

    @Autowired
    public void setPlatformUserService(PlatformUserService platformUserService) {
        this.platformUserService = platformUserService;
    }

    @Autowired
    public void setPlatformTenantService(PlatformTenantService platformTenantService) {
        this.platformTenantService = platformTenantService;
    }

    /**
     * @param tenantName 租户名称
     * @param userInfo   用户基础信息 用户账户 / 用户手机号 / 用户邮箱
     * @return 用户信息
     * @throws UsernameNotFoundException 异常
     */
    @Override
    public UserDetails loadUserByTenantAndUserInfo(String tenantName, String userInfo) throws UsernameNotFoundException {
        try {
            PlatformUser platformUser;
            // 手机号
            if (Validator.isMobile(userInfo)) {
                platformUser = platformUserService.getUserByPhone(tenantName, userInfo);
            }
            // 邮箱
            else if (Validator.isEmail(userInfo)) {
                platformUser = platformUserService.getUserByEmail(tenantName, userInfo);
            }
            // 用户名
            else {
                platformUser = platformUserService.getUserByUsername(tenantName, userInfo);
            }

            if (ObjectUtil.isEmpty(platformUser)) {
                throw new UsernameNotFoundException("根据用户信息" + userInfo + "未查询到用户");
            }

            platformUser.setTenantName(tenantName);

            PlatformTenantQueryDto platformTenantQueryDto = platformTenantService.info(platformUser.getTenantId());

            if (ObjectUtil.isEmpty(platformTenantQueryDto)) {
                throw new UsernameNotFoundException("根据用户信息" + userInfo + "未查询到关联租户");
            }

            if (!platformTenantQueryDto.getStatus()) {
                throw new UsernameNotFoundException("租户已被禁用，请联系平台管理员");
            }

            // 权限字符串列表
            List<String> permissions = new ArrayList<>();
            // 超级管理员
            if (Constant.PLATFORM_SUPER_USER.equals(platformUser.getUserCode()) || Constant.SYSTEM_SUPER_USER.equals(platformUser.getUserCode())) {
                permissions.add("*");
                permissions.add("*:*:*");
                permissions.add("ROLE_*");
            }

            // 安全角色列表
            List<SecurityRole> securityRoleList = new ArrayList<>();
            // 安全权限列表
            List<SecurityPower> securityPowerList = new ArrayList<>();

            List<PlatformRole> platformRoles = platformUser.getPlatformRoles();
            if (ObjectUtil.isNotEmpty(platformRoles)) {
                platformRoles.forEach(platformRole -> {
                    if (Constant.PLATFORM_SUPER_ROLE.equals(platformRole.getRoleCode()) || Constant.SYSTEM_SUPER_ROLE.equals(platformRole.getRoleCode())) {
                        permissions.add("*");
                        permissions.add("*:*:*");
                        permissions.add("ROLE_*");
                    }
                    // permissions.add(platformRole.getRoleCode().startsWith("ROLE_") ? platformRole.getRoleCode() : "ROLE_" + platformRole.getRoleCode());
                    securityRoleList.add(SecurityRole.builder().record(Record.getRecordByModel(platformRole)).build());
                });
            }

            List<PlatformMenuPower> platformMenuPowers = platformUser.getPlatformMenuPowers();
            if (ObjectUtil.isNotEmpty(platformMenuPowers)) {
                platformMenuPowers.forEach(platformMenuPower -> {
                    // permissions.add(platformMenuPower.getPowerCode());
                    securityPowerList.add(SecurityPower.builder().record(Record.getRecordByModel(platformMenuPower)).build());
                });
            }

            Record record = Record.getRecordByModel(platformUser);
            record.remove("loginIp");
            record.remove("loginDate");
            record.remove("pwdUpdateDate");
            record.remove("status");
            record.remove("deleted");
            record.remove("platformRoleList");
            record.remove("platformMenuPowerList");
            record.set("permissions", permissions);
            return SecurityUser.builder().record(record).tenant(Record.getRecordByModel(platformTenantQueryDto)).securityRoles(securityRoleList).securityPowers(securityPowerList).build();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new UsernameNotFoundException(ex.getMessage(), ex);
        }
    }

    /**
     * @param username the username identifying the user whose data is required.
     * @return 用户信息
     * @throws UsernameNotFoundException 异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String[] tenantNameAndUserName = username.split("&");
        if (ObjectUtil.isEmpty(tenantNameAndUserName) || tenantNameAndUserName.length != 2) {
            throw new UsernameNotFoundException("没有给定租户");
        }
        return this.loadUserByTenantAndUserInfo(tenantNameAndUserName[0], tenantNameAndUserName[1]);
    }

}
